﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;
using Microsoft.Expression.Controls;
using Microsoft.Expression.Media;

namespace DataArtistConnections
{
    //public static class Connections
    //{
    //    private static List<TrackConnection> TrackConnections { get; set; }
    //    private static FrameworkElement FromElement { get; set; }
    //    private static FrameworkElement ToElement { get; set; }

    //    static Connections()
    //    {
    //        TrackConnections = new List<TrackConnection>();
    //    }

    //    public static void Adjust(FrameworkElement connectFromElement, FrameworkElement connectToElement)
    //    {
    //        Add(connectFromElement, connectToElement, adjustOnly: true);

    //        foreach (var connect in TrackConnections.Where(connect => connectFromElement == connect.ToElement))
    //        {
    //            Add(connect.FromElement, connect.ToElement, adjustOnly: true);
    //        }
    //    }

    //    //handle objects that are only connected to (they own no connections to other objects)
    //    public static void Adjust(FrameworkElement connectToElement)
    //    {
    //        foreach (var connect in TrackConnections.Where(connect => connectToElement == connect.ToElement))
    //        {
    //            Add(connect.FromElement, connect.ToElement, adjustOnly: true);
    //        }
    //    }

    //    public static void Add(FrameworkElement connectFromElement, FrameworkElement connectToElement, SolidColorBrush color = null, int strokeThickness = 2, double bendAmount = .1, double arrowSize = 5, DoubleCollection strokeDashArray = null, string arrowType = null, bool shadow = false, bool adjustOnly = false)
    //    {
    //        var parent = connectFromElement.Parent as Panel;
            
    //        FromElement = connectFromElement;
    //        ToElement = connectToElement;

    //        var connectFromX = connectFromElement.Left();
    //        var connectFromY = connectFromElement.Top();
    //        var connectToX = connectToElement.Left();
    //        var connectToY = connectToElement.Top();

    //        switch (PositionKey(connectFromElement, connectToX - connectFromX, connectToY - connectFromY))
    //        {
    //            case "RA": //right & above
    //            case "LA": //left & above
    //            case "SA": //same horizontal & above
    //                AboveOrBelow(connectToElement, connectFromElement, ref connectFromX, ref connectFromY, ref connectToX);
    //                break;

    //            case "LB": //left & below
    //            case "RB": //right & below
    //                AboveOrBelow(connectFromElement, connectToElement, ref connectToX, ref connectToY, ref connectFromX);
    //                break;

    //            case "SB": //same vertical & below
    //                AboveOrBelow(connectToElement, connectFromElement, ref connectFromX, ref connectFromY, ref connectToX);
    //                break;

    //            case "RS": //right & same vertical
    //                RightOrLeft(connectFromElement, connectToElement, ref connectToY, ref connectToX, ref connectFromY);
    //                break;

    //            case "LS": //left & same vertical
    //                RightOrLeft(connectToElement, connectFromElement, ref connectFromY, ref connectFromX, ref connectToY);
    //                break;

    //            case "SS":
    //                //do nothing if same horizontal and vertical
    //                break;
    //        }

    //        Canvas.SetZIndex(connectFromElement, 1);
    //        Canvas.SetZIndex(connectToElement, 1);

    //        if (adjustOnly == false)
    //        {
    //            AddConnection(parent, connectFromX, connectFromY, connectToX, connectToY, color, strokeThickness, bendAmount, arrowSize, strokeDashArray, arrowType, shadow);
    //        }
    //        else
    //        {
    //            AdjustConnection(parent, connectFromX, connectFromY, connectToX, connectToY);
    //        }
    //    }

    //    private static void AddConnection(Panel parent, double x1, double y1, double x2, double y2, SolidColorBrush color, int strokeThickness, double bendAmount, double arrowSize, DoubleCollection strokeDashArray, string arrowType, bool shadow)
    //    {
    //        if (color == null)
    //        {
    //            color = new SolidColorBrush(Colors.Black);
    //        }

    //        double height = Math.Abs(y2 - y1);
    //        double width = Math.Abs(x2 - x1);
    //        double adjY = 0;
    //        double adjX = 0;

    //        var cornerType = CalcCornerType(x1, y1, x2, y2, width, height, ref adjX, ref adjY);

    //        var line = new LineArrow
    //        {
    //            //Name = Guid.NewGuid().ToString(),
    //            StartCorner = cornerType,
    //            Stroke = color,
    //            BendAmount = bendAmount,
    //            ArrowSize = arrowSize,
    //            StrokeDashArray = strokeDashArray,
    //            EndArrow = arrowType.ArrowTypeFromString(),
    //            Height = height,
    //            Width = width,
    //            StrokeThickness = strokeThickness
    //        };

    //        if (shadow == true)
    //        {
    //            line.Effect = new DropShadowEffect { Color = Colors.Gray, BlurRadius = 5 };
    //        }

    //        parent.Children.Add(line);

    //        line.SetValue(Canvas.LeftProperty, x1 + adjX);
    //        line.SetValue(Canvas.TopProperty, y1 + adjY);

    //        TrackConnections.Add(new TrackConnection { FromElement = FromElement, ToElement = ToElement, Line = line });

    //        Canvas.SetZIndex(line, 0);
    //    }

    //    private static void AdjustConnection(Panel parent, double x1, double y1, double x2, double y2)
    //    {
    //        foreach (var connectionObject in TrackConnections)
    //        {
    //            if (connectionObject.FromElement == FromElement && connectionObject.ToElement == ToElement)
    //            {
    //                double height = Math.Abs((y2 - parent.Top()) - (y1 - parent.Top()));
    //                double width =  Math.Abs((x2 - parent.Left()) - (x1 - parent.Left()));
    //                double adjY = 0;
    //                double adjX = 0;

    //                var cornerType = CalcCornerType(x1, y1, x2, y2, width, height, ref adjX, ref adjY);

    //                connectionObject.Line.SetValue(Canvas.TopProperty, (y1 - parent.Top()) + adjY);
    //                connectionObject.Line.SetValue(Canvas.LeftProperty, (x1 - parent.Left()) + adjX);
    //                connectionObject.Line.StartCorner = cornerType;
    //                connectionObject.Line.Height = Math.Abs(height);
    //                connectionObject.Line.Width = Math.Abs(width);
    //            }
    //        }
    //    }

    //    private static string PositionKey(FrameworkElement connectFromElement, double diffX, double diffY)
    //    {
    //        string verticalPosition;
    //        string horizontalPosition;

    //        if (Math.Abs(diffY) < connectFromElement.Height)
    //        {
    //            diffY = 0;
    //        }

    //        if (diffX == 0)
    //        {
    //            horizontalPosition = "S"; //same horizontal
    //        }
    //        else
    //        {
    //            if (diffX > 0)
    //            {
    //                horizontalPosition = "L"; //left
    //            }
    //            else
    //            {
    //                horizontalPosition = "R"; //right
    //            }
    //        }

    //        if (diffY == 0)
    //        {
    //            verticalPosition = "S"; //same vertical
    //        }
    //        else
    //        {
    //            if (diffY > 0)
    //            {
    //                verticalPosition = "A"; //above
    //            }
    //            else
    //            {
    //                verticalPosition = "B"; //below
    //            }
    //        }

    //        return horizontalPosition + verticalPosition;
    //    }

    //    private static void AboveOrBelow(FrameworkElement element1, FrameworkElement element2, ref double p1, ref double p2, ref double p3)
    //    {
    //        p1 += element2.Width / 2;
    //        p2 += element2.Height;
    //        p3 += element1.Width / 2;
    //    }

    //    private static void RightOrLeft(FrameworkElement element1, FrameworkElement element2, ref double p1, ref double p2, ref double p3)
    //    {
    //        p1 += element2.Height / 2;
    //        p2 += element2.Width;
    //        p3 += element1.Height / 2;
    //    }

    //    private static CornerType CalcCornerType(double x1, double y1, double x2, double y2, double width, double height, ref double adjX, ref double adjY)
    //    {
    //        var cornerType = CornerType.TopLeft;

    //        if (y2 < y1 && x2 < x1)
    //        {
    //            cornerType = CornerType.BottomRight;
    //            adjY = -height;
    //            adjX = -width;
    //        }
    //        else
    //        {
    //            if (y2 < y1)
    //            {
    //                cornerType = CornerType.BottomLeft;
    //                adjY = -height;
    //            }

    //            if (x2 < x1)
    //            {
    //                cornerType = CornerType.TopRight;
    //                adjX = -width;
    //            }
    //        }
    //        return cornerType;
    //    }

    //    public static double Left(this Object value)
    //    {
    //        var g = ((FrameworkElement)value).TransformToVisual(Application.Current.RootVisual);
    //        var offset = g.Transform(new Point(0, 0));
    //        return offset.X;
    //    }

    //    public static double Top(this Object value)
    //    {
    //        var g = ((FrameworkElement)value).TransformToVisual(Application.Current.RootVisual);
    //        var offset = g.Transform(new Point(0, 0));
    //        return offset.Y;
    //    }

    //    public static ArrowType ArrowTypeFromString(this string value)
    //    {
    //        switch (value)
    //        {
    //            case "Arrow":
    //                return ArrowType.Arrow;

    //            case "NoArrow":
    //                return ArrowType.NoArrow;

    //            case "OpenArrow":
    //                return ArrowType.OpenArrow;

    //            case "OvalArrow":
    //                return ArrowType.OvalArrow;

    //            case "StealthArrow":
    //                return ArrowType.StealthArrow;

    //            default://change this value for a default arrow type
    //                return ArrowType.StealthArrow;
    //        }
    //    }
    //}
}
